UI
main.dart
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:b/news_home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(textTheme: GoogleFonts.poppinsTextTheme()),
home: const NewsHomePage(),
);
}
}
news_home_page.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:b/Model/news_model.dart';
import 'package:b/news_detail.dart';
class NewsHomePage extends StatelessWidget {
const NewsHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.only(left: 20),
child: ListView(
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Explore",
style: TextStyle(fontSize: 37, fontWeight: FontWeight.bold),
),
const SizedBox(
height: 12,
),
// for search bar
searchabar(),
const SizedBox(
height: 20,
),
forImages(context),
const SizedBox(
height: 10,
),
const Padding(
padding: EdgeInsets.only(right: 20),
child: Row(
children: [
Text(
"Hot topic",
style:
TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
Spacer(),
Text(
"See all",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black45,
),
),
],
),
),
const SizedBox(
height: 10,
),
SizedBox(
height: 55,
width: MediaQuery.of(context).size.width,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: topicItems
.sublist(0, 3)
.length, // we need only first three items from model
itemBuilder: (context, index) {
final topic = topicItems.sublist(0, 3)[index];
return Container(
margin: const EdgeInsets.only(right: 10),
height: 55,
width: MediaQuery.of(context).size.width / 3.5,
decoration: BoxDecoration(
color: topic.color,
borderRadius: BorderRadius.circular(15)),
child: Row(
children: [
Image.asset(
topic.image,
height: 45,
width: 45,
),
Text(
topic.name,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.white),
)
],
),
);
}),
),
const SizedBox(
height: 10,
),
SizedBox(
height: 55,
width: MediaQuery.of(context).size.width,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: topicItems
.sublist(3)
.length, // we need only remaining items from model
itemBuilder: (context, index) {
final topic = topicItems.sublist(3)[index];
return Container(
margin: const EdgeInsets.only(right: 10),
height: 55,
width: MediaQuery.of(context).size.width / 3.2,
decoration: BoxDecoration(
color: topic.color,
borderRadius: BorderRadius.circular(15)),
child: Row(
children: [
Image.asset(
topic.image,
height: 45,
width: 45,
),
Text(
topic.name,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.white),
)
],
),
);
},
),
),
const Padding(
padding: EdgeInsets.only(right: 20, top: 20),
child: Row(
children: [
Text(
"Your news",
style:
TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
Spacer(),
Text(
"See all",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black45,
),
),
],
),
),
const SizedBox(
height: 15,
),
Expanded(
child: SizedBox(
width: MediaQuery.of(context).size.width,
child: ListView.builder(
shrinkWrap: true,
itemCount: newsItems.length,
itemBuilder: (context, index) {
final news = newsItems[index];
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
DetailNews(news: news)));
},
child: Padding(
padding: const EdgeInsets.only(bottom: 10, right: 20),
child: Material(
borderRadius: BorderRadius.circular(20),
elevation: 1,
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(
left: 10, right: 20),
child: Container(
height: 100,
width: 90,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(news.image),
fit: BoxFit.cover),
borderRadius: BorderRadius.circular(10),
),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width:
MediaQuery.of(context).size.width / 2,
child: Text(
news.newsTitle,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
const SizedBox(
height: 15,
),
Row(
children: [
Container(
decoration: BoxDecoration(
color:
news.color.withOpacity(0.2),
borderRadius:
BorderRadius.circular(8)),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8, vertical: 2),
child: Text(
news.newsCategories,
style: TextStyle(
color: news.color,
fontWeight: FontWeight.bold,
),
),
),
),
Padding(
padding:
const EdgeInsets.only(left: 145),
child: Text(
news.time,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black45),
),
),
],
),
const SizedBox(
height: 15,
)
],
)
],
),
),
),
);
},
),
),
),
],
),
),
),
);
}
Padding forImages(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(right: 20),
child: SizedBox(
height: MediaQuery.of(context).size.height / 4.9,
width: MediaQuery.of(context).size.width,
child: Stack(
children: [
Positioned(
left: 0,
child: Image.asset(
"Images/c..png",
height: MediaQuery.of(context).size.height / 5.5,
width: MediaQuery.of(context).size.width / 2.1,
),
),
Positioned(
right: 0,
child: Image.asset(
"Images/d.png",
height: MediaQuery.of(context).size.height / 5.5,
width: MediaQuery.of(context).size.width / 2.5,
))
],
),
),
);
}
Padding searchabar() {
return Padding(
padding: const EdgeInsets.only(right: 20),
child: Container(
height: 55,
decoration: BoxDecoration(
color: const Color.fromARGB(31, 151, 146, 146),
borderRadius: BorderRadius.circular(20)),
child: const Center(
child: TextField(
decoration: InputDecoration(
hintText: "Search",
hintStyle: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black45),
prefixIcon: Icon(
Icons.search,
size: 30,
color: Colors.black45,
),
border: InputBorder.none,
),
),
),
),
);
}
}
news_details.dart
import 'package:flutter/material.dart';
import 'package:b/Model/news_model.dart';
class DetailNews extends StatelessWidget {
const DetailNews({super.key, required this.news});
final Yournews news;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const Icon(
Icons.arrow_back,
size: 30,
color: Color.fromARGB(255, 73, 98, 223),
),
),
const SizedBox(
height: 20,
),
Text(
"${news.date} . ${news.newsCategories.toLowerCase()}",
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black45),
),
const SizedBox(
height: 12,
),
Text(
news.newsTitle,
style: const TextStyle(
fontSize: 33,
height: 1.2,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 20,
),
Container(
height: 250,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(news.newsImage),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(20)),
),
const SizedBox(
height: 15,
),
Text(
news.description,
style: const TextStyle(
fontSize: 21,
height: 1.6,
),
),
const SizedBox(
height: 15,
),
const Text(
"So what's changed?",
style: TextStyle(
fontSize: 21,
fontWeight: FontWeight.bold,
),
),
Text(
news.description,
style: const TextStyle(
fontSize: 21,
height: 1.6,
),
),
Text(
news.description,
style: const TextStyle(
fontSize: 21,
height: 1.6,
),
),
],
),
),
),
),
bottomSheet: Container(
height: 75,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: const [
BoxShadow(spreadRadius: 1, blurRadius: 2, offset: Offset(0, 3))
],
borderRadius: BorderRadius.circular(50)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(left: 17),
child: Container(
height: 50,
width: MediaQuery.of(context).size.width / 2,
decoration: BoxDecoration(
color: const Color(0xFFDDEAFF),
borderRadius: BorderRadius.circular(60)),
child: Row(
children: [
const SizedBox(
width: 13,
),
Image.asset(
"Images/chat.png",
height: 45,
),
const Text(
"Add a comment",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
color: Color(0xFF277AFF),
),
),
],
),
),
),
CircleAvatar(
radius: 25,
backgroundColor: const Color(0xFFEDE3FA),
child: Image.asset(
"Images/icon.png",
height: 32,
),
),
CircleAvatar(
radius: 25,
backgroundColor: const Color(0xFFFFF7E2),
child: Image.asset(
"Images/star.png",
height: 32,
),
),
const CircleAvatar(
radius: 25,
backgroundColor: Color(0xFFD9F9F5),
child:Icon(Icons.more_vert,size: 35,color: Color(0xFF00D9BC),)
),
SizedBox(width: 15,)
],
),
),
);
}
}
Model/news_model.dart
import 'package:flutter/material.dart';
class HotTopic {
String image;
String name;
Color color;
HotTopic({
required this.color,
required this.image,
required this.name,
});
}
List topicItems = [
HotTopic(
color: const Color(0xFF3180FF),
image: "Images/music program.png",
name: 'World',
),
HotTopic(
color: const Color(0xFFFB3C5F),
image: "Images/music program.png",
name: 'Tech',
),
HotTopic(
color: const Color(0xFF57CBFF),
image: "Images/music.png",
name: 'Music',
),
HotTopic(
color: const Color(0xFFFF7A23),
image: "Images/travel.png",
name: 'Travel',
),
HotTopic(
color: const Color(0xFF0AE3C6),
image: "Images/kitchen.png",
name: 'Kitchen',
),
HotTopic(
color: const Color(0xFF8349DF),
image: "Images/fashion.png",
name: 'Fashion',
),
];
// model for your news
class Yournews {
String image;
String newsImage;
String newsTitle;
String newsCategories;
String time;
String date;
Color color;
String description;
Yournews({
required this.image,
required this.newsImage,
required this.newsTitle,
required this.newsCategories,
required this.time,
required this.date,
required this.color,
required this.description,
});
}
List newsItems = [
Yournews(
description: "Before embarking on a journey to travel the world, it's essential to prepare adequately to ensure a smooth and enjoyable experience.Research the countries and regions you plan to visit. ",
newsImage: "Images/travelling.png",
image: "Images/news travel.png",
newsTitle: 'What i know before travelling the world',
newsCategories: "TRAVEL",
date: 'Sunday 2 March 2024',
time: '2m',
color: const Color(0xFFFF7A23),
),
Yournews(
description: "Background music can greatly enhance your focus and productivity while programming. The best music for programming varies from person to person, as it depends on personal preferences and what helps you concentrate.",
newsImage: "Images/music program.png",
image: "Images/programming music.png",
newsTitle: 'Background music for programming',
newsCategories: "MUSIC",
date: 'Saturday 29 Nov 2023',
time: '4h',
color: const Color(0xFF57CBFF),
),
Yournews(
description: "That iteration of the paper served readers well for the past 17 years, but it needed to be updated. From this week, The Economist has a fresher look, with typefaces better suited to both print and digital formats.",
newsImage: "Images/design news.png",
image: "Images/tech image.png",
newsTitle: "How to redesign a 175-year-old newspaper",
newsCategories: "TECH",
date: 'Saturday 29 Nov 2019',
time: '10h',
color: const Color(0xFFFB3C5F),
),
Yournews(
description:"The term world can have different meanings depending on the context in which it is used:Planet Earth: In a literal sense, world refers to the planet we inhabit, including its land, oceans, atmosphere, and all living organisms.",
newsImage: "Images/world news.png",
image: "Images/world image.png",
newsTitle: "Whats your openion about the world",
newsCategories: "WORLD",
date: 'Saturday 29 Nov 1101',
time: '∞',
color: const Color(0xFF3180FF),
),
];